#pragma once
#include<iostream>
#include<vector>
#include<unordered_map>

namespace bit 
{
	template<class type>
	class Shared_ptr 
	{
	  public:
		void addRef() {
			(* _ref_count)++;
	    }
		void cutRef() {
			(* _ref_count)--;
		}
		Shared_ptr(type* ptr):_ptr(ptr),_ref_count(nullptr) {
			for (auto& x : _tables) {
				if (x.first == ptr) {
					_ref_count = x.second;
					
				}
			}
			if (!_ref_count) {
				_ref_count = new int;
				_tables[_ptr] = _ref_count;
				*_ref_count = 0;
				addRef();
			}
			
		}
		Shared_ptr(Shared_ptr<type>& value)
		:_ptr(value->_ptr)
		,_ref_count(value->_ref_count)
		{
			addRef();
		}
		~Shared_ptr() {
			cutRef();
			if ((*_ref_count) == 0) {
				auto it = _tables.find(_ptr);
				_tables.erase(it);
				delete _ptr;
				delete _ref_count;
			}
		}
		type& operator*() {
			return *_ptr;
		}
		type*& operator->() {
			return _ptr;
		}
	  private:
		type* _ptr;
		int* _ref_count;
		static std::unordered_map<type*,int*> _tables;
	};
}